package com.tip.calculator.view;

import java.text.DecimalFormat;

import com.tip.calculator.R;
import com.tip.calculator.listener.TextListener;
import com.tip.calculator.model.Tip;
import com.tip.calculator.service.TipService;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;

public class TipActivity extends Activity {

	private Tip tip;
	private TipService tipService;
	private EditText numberOfGuests, billTotal, billDeductions, taxes;
	private RatingBar ratingBar;
	private TextView tipRate, totalTip, perPersonTip, total;
	private Button tipTailoring;
	private DecimalFormat dec;
	private float min, max;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.tip);

		tip = new Tip();
		tipService = new TipService(tip);
		dec = new DecimalFormat("##.##");

		numberOfGuests = (EditText) findViewById(R.id.etNumOfGuests);
		billTotal = (EditText) findViewById(R.id.etBillTotal);
		billDeductions = (EditText) findViewById(R.id.etBillDeductions);
		taxes = (EditText) findViewById(R.id.etTaxes);
		ratingBar = (RatingBar) findViewById(R.id.rbQuality);
		tipRate = (TextView) findViewById(R.id.tvTipRate);
		totalTip = (TextView) findViewById(R.id.tvTotalTip);
		perPersonTip = (TextView) findViewById(R.id.tvPerPerson);
		total = (TextView) findViewById(R.id.tvTotal);
		tipTailoring = (Button) findViewById(R.id.btTipTailoring);

		getPrefsAndUpdate();

		// Number of Guests Listener
		numberOfGuests.addTextChangedListener(new TextListener() {
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if (s.length() <= 0) {
					tip.setNumberOfGuests(1);
					updateAll();
				} else {
					int guests = Integer.parseInt(s.toString());
					if (guests == 0) {
						showPopUp("Number of guests cannot be 0. The value is reset to default.");
						numberOfGuests.setText("1");
					} else if (guests > 99) {
						showPopUp("Number of guests cannot exceed 99. The value is reset to default.");
						numberOfGuests.setText("1");
					} else {
						tip.setNumberOfGuests(guests);
						updateAll();
					}

				}
			}
		});

		// Rating Bar Listener
		ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
			public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
				tip.setTipRate(rating);
				tipRate.setText(dec.format(tipService.getPercentageFromTipRating(rating, min, max)));
				updateAll();
			}
		});

		// Bill Total Listener
		billTotal.addTextChangedListener(new TextListener() {
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if (s.length() <= 0) {
					tip.setBillTotal(0);
					updateAll();
				} else {
					try {
						tip.setBillTotal(Float.parseFloat(s.toString()));
						updateAll();
					} catch (Exception e) {
					}
				}
			}
		});

		// Bill Deductions Listener
		billDeductions.addTextChangedListener(new TextListener() {
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if (s.length() <= 0) {
					tip.setBillDeduction(0);
					updateAll();
				} else {
					try {
						float deduction = Float.parseFloat(s.toString());
						if (deduction > tip.getBillTotal()) {
							showPopUp("Deductions cannot be greater than Bill Total. Enter a different amount.");
							billDeductions.setText("");
						} else {
							tip.setBillDeduction(deduction);
							updateAll();
						}
					} catch (Exception e) {
					}
				}
			}
		});

		// Taxes Listener
		taxes.addTextChangedListener(new TextListener() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if (s.length() <= 0) {
					tip.setTaxAmount(0);
					updateAll();
				} else {
					try {
						float tax = Float.parseFloat(s.toString());
						if (tax > tip.getBillTotal()) {
							showPopUp("Tax cannot be greater than Bill Total. Enter a different amount.");
							taxes.setText("");
						} else {
							tip.setTaxAmount(tax);
							updateAll();
						}
					} catch (Exception e) {
					}
				}
			}
		});
	}

	@Override
	protected void onResume() {
		super.onResume();

		getPrefsAndUpdate();

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		MenuInflater blowUp = getMenuInflater();
		blowUp.inflate(R.menu.tipmenu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);
		switch (item.getItemId()) {
			case R.id.config :
				try {
					Class ourClass = Class.forName("com.tip.calculator.view.Configuration");
					Intent i = new Intent(TipActivity.this, ourClass);
					startActivity(i);
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				break;
			case R.id.help :
				try {
					String perPerson = dec.format(tipService.getPerPersonTip());
					Bundle bundle = new Bundle();
					bundle.putInt("numberOfGuests", tip.getNumberOfGuests());
					bundle.putSerializable("myTip", tip);
					Class ourClass = Class.forName("com.tip.calculator.view.TipTailoring");
					Intent i = new Intent(TipActivity.this, ourClass);
					i.putExtras(bundle);
					startActivity(i);
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;

			case R.id.exit :
				finish();
				break;
		}
		return false;
	}

	public void updateAll() {
		totalTip.setText(dec.format(tipService.getTotalTip()));

		final float perPerson = tipService.getPerPersonTip();
		tip.setPerPersonTip(perPerson);
		
		if (perPerson > 0) {
			tipTailoring.setEnabled(true);
			tipTailoring.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					Bundle bundle = new Bundle();
					bundle.putInt("numberOfGuests", tip.getNumberOfGuests());
					bundle.putFloat("totalTip", tip.getTotalTip());
					bundle.putFloat("perPersonTip", perPerson);
					try {
						Class ourClass = Class.forName("com.tip.calculator.view.TipTailoring");
						Intent i = new Intent(v.getContext(), ourClass);
						i.putExtras(bundle);
						startActivity(i);
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		}
		perPersonTip.setText(dec.format(perPerson));
		total.setText(dec.format(tipService.getTotalBillAndTip()));
	}

	public void showPopUp(String error) {
		AlertDialog alert = new AlertDialog.Builder(this).setTitle("Input Error!")
				.setMessage(error).setNeutralButton("Okay", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						Log.d("AlertDialog", "Neutral");
					}
				}).show();
	}

	public void getPrefsAndUpdate() {

		SharedPreferences getPrefs = PreferenceManager
				.getDefaultSharedPreferences(getBaseContext());

		boolean tipRange = getPrefs.getBoolean("checkBox", false);
		boolean showTax = getPrefs.getBoolean("taxCheckBox", false);
		boolean showDeduction = getPrefs.getBoolean("deductionCheckBox", false);

		// Set the new minimum and maximum tip range from the configuration
		if (tipRange) {
			try {
				min = Float.parseFloat(getPrefs.getString("min", ""));
				max = Float.parseFloat(getPrefs.getString("max", ""));
			} catch (Exception e) {
				min = 0;
				max = 25;
			}
		} else {
			min = 0;
			max = 25;
		}

		// If the user selected a rating already before changing configuration,
		// then update everything based on configurations
		float rating = ratingBar.getRating();
		tip.setTipRate(rating);
		tipRate.setText(dec.format(tipService.getPercentageFromTipRating(rating, min, max)));
		updateAll();

		// Check taxes and deductions check boxes to enable or disable
		if (showTax) {
			taxes.setEnabled(true);
			try {
				float tax = Float.parseFloat(taxes.getText().toString());
				if (tax > tip.getBillTotal()) {
					showPopUp("Tax cannot be greater than Bill Total. Enter a different amount.");
					taxes.setText("");
				} else {
					tip.setTaxAmount(tax);
					updateAll();
				}
			} catch (Exception e) {
			}
		} else {
			taxes.setEnabled(false);
			tip.setTaxAmount(0);
			updateAll();
		}

		if (showDeduction) {
			billDeductions.setEnabled(true);
			try {
				float deduction = Float.parseFloat(billDeductions.getText().toString());
				if (deduction > tip.getBillTotal()) {
					showPopUp("Deductions cannot be greater than Bill Total. Enter a different amount.");
					billDeductions.setText("");
				} else {
					tip.setBillDeduction(deduction);
					updateAll();
				}
			} catch (Exception e) {
			}
		} else {
			billDeductions.setEnabled(false);
			tip.setBillDeduction(0);
			updateAll();
		}
	}

}
